// 对象字段描述定义
#ifndef __XJ_OBJECT_DESCRIPTOR_H__
#define __XJ_OBJECT_DESCRIPTOR_H__
#include <stdint.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif


typedef struct st_obj_desc_s  st_obj_desc_t;

// 对象结构字段类型
enum E_OBJECT_FIELD_TYPE
{
    E_OFT_NONE = 0,
    E_OFT_STRING,    // 字符串数组非指针, 指针请使用E_OFT_ARR_HEAP
    E_OFT_INT8,
    E_OFT_UINT8,
    E_OFT_INT16,
    E_OFT_UINT16,
    E_OFT_INT32,
    E_OFT_UINT32,
    E_OFT_INT64,
    E_OFT_UINT64,
    E_OFT_FLOAT32,
    E_OFT_FLOAT64,
    E_OFT_PTR,
    E_OFT_STRUCT,
    E_OFT_ARR_STACK,  // 一维数组结构,栈内存,定义时指定数组大小,
    E_OFT_ARR_HEAP,   // 一维数组结构,堆内存,需要指定长度字段,需要释放
    E_OFT_END
};

// 对象结构字段描述单元
struct st_obj_desc_s
{
    const char *    name;            // 名称
    int8_t          type;            // 类型
    uint32_t        offset;          // 偏移量
    uint64_t        size;            // 大小
    int32_t         noffset;         // 用于数组，数组长度的偏移量 -1表示不是数组
    int8_t          mtype;           // 用于数组，数组成员的类型
    uint64_t        msize;           // 用于数组，数组成员的大小
    int32_t         info_field_size; // 用于自定义结构体，结构体描述实例字段个数
    st_obj_desc_t  *info_ptr;        // 用于自定义结构体，结构体描述实例指针 NULL表示不是自定义结构体
    int8_t          parent_expand;   // 公共公用结构体JSON父层结构是否展开, 0-不展开 1-展开
};

// 忽略字段名 "-"

// 定义结构体成员信息数组
#define ST_OBJ_DESC_TYPE(obj_type_def) \
    static st_obj_desc_t st_obj_desc_##obj_type_def[] = { 

// 定义标准数据类型成员信息
#define ST_OBJ_DESC_DEF_VAR(obj_type_def, fieldname, field_type_enum) \
    { #fieldname,  field_type_enum, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname), -1, 0, 0, 0, 0 , 0 /* parent_expand */}, 

// 定义标准数据类型数组成员信息 栈内存
#define ST_OBJ_DESC_DEF_VARS_STACK(obj_type_def, fieldname, field_obj_type, field_type_enum) \
    { #fieldname, E_OFT_ARR_STACK, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname), -1,field_type_enum, sizeof(field_obj_type), \
        0, \
        0\
        , 0 /* parent_expand */\
    },
// 定义标准数据类型数组成员信息 堆内存
#define ST_OBJ_DESC_DEF_VARS_HEAP(obj_type_def, fieldname, lenghtname, field_obj_type, field_type_enum) \
    { #fieldname, E_OFT_ARR_HEAP, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname),offsetof(obj_type_def, lenghtname),field_type_enum, sizeof(field_obj_type), \
        0, \
        0 \
        , 0 /* parent_expand */\
    },

// 定义自定义结构体成员信息
#define ST_OBJ_DESC_DEF_OBJ(obj_type_def, fieldname, field_obj_type) \
    { #fieldname, E_OFT_STRUCT, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname), -1, 0, 0, sizeof(st_obj_desc_##field_obj_type)/sizeof(st_obj_desc_t),(void *)&st_obj_desc_##field_obj_type , 0 /* parent_expand */},

// 定义自定义结构体数组成员信息 栈内存
#define ST_OBJ_DESC_DEF_OBJS_STACK(obj_type_def, fieldname, field_obj_type) \
    { #fieldname, E_OFT_ARR_STACK, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname),-1,E_OFT_STRUCT, sizeof(field_obj_type), \
        sizeof(st_obj_desc_##field_obj_type)/sizeof(st_obj_desc_t), \
        (void *)&st_obj_desc_##field_obj_type\
        , 0 /* parent_expand */\
    },
// 定义自定义结构体数组成员信息 堆内存
#define ST_OBJ_DESC_DEF_OBJS_HEAP(obj_type_def, fieldname, lenghtname, field_obj_type) \
    { #fieldname, E_OFT_ARR_HEAP, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname),offsetof(obj_type_def, lenghtname),E_OFT_STRUCT, sizeof(field_obj_type), \
        sizeof(st_obj_desc_##field_obj_type)/sizeof(st_obj_desc_t), \
        (void *)&st_obj_desc_##field_obj_type\
        , 0 /* parent_expand */\
    },


// 定义标准数据类型成员信息JSON别名
#define ST_OBJ_DESC_JSON_DEF_VAR(obj_type_def, fieldname, field_type_enum, jsonname) \
    { #jsonname,  field_type_enum, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname), -1, 0, 0, 0, 0 , 0 /* parent_expand */}, 

// 定义标准数据类型数组成员信息JSON别名 栈内存
#define ST_OBJ_DESC_JSON_DEF_VARS_STACK(obj_type_def, fieldname, field_obj_type, field_type_enum, jsonname) \
    { #jsonname, E_OFT_ARR_STACK, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname), -1,field_type_enum, sizeof(field_obj_type), \
        0, \
        0\
        , 0 /* parent_expand */\
    },
// 定义标准数据类型数组成员信息JSON别名 堆内存
#define ST_OBJ_DESC_JSON_DEF_VARS_HEAP(obj_type_def, fieldname, lenghtname, field_obj_type, field_type_enum, jsonname) \
    { #jsonname, E_OFT_ARR_HEAP, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname),offsetof(obj_type_def, lenghtname),field_type_enum, sizeof(field_obj_type), \
        0, \
        0 \
        , 0 /* parent_expand */\
    },

// 定义自定义结构体成员信息
#define ST_OBJ_DESC_JSON_DEF_OBJ(obj_type_def, fieldname, field_obj_type, jsonname) \
    { #jsonname, E_OFT_STRUCT, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname), -1, 0, 0, sizeof(st_obj_desc_##field_obj_type)/sizeof(st_obj_desc_t),(void *)&st_obj_desc_##field_obj_type , 0 /* parent_expand */},

// 定义自定义结构体成员信息
#define ST_OBJ_DESC_JSON_DEF_OBJ_EXPAND(obj_type_def, fieldname, field_obj_type, jsonname) \
    { #jsonname, E_OFT_STRUCT, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname), -1, 0, 0, sizeof(st_obj_desc_##field_obj_type)/sizeof(st_obj_desc_t),(void *)&st_obj_desc_##field_obj_type , 1 /* parent_expand */},

// 定义自定义结构体数组成员信息 栈内存
#define ST_OBJ_DESC_JSON_DEF_OBJS_STACK(obj_type_def, fieldname, field_obj_type, jsonname) \
    { #jsonname, E_OFT_ARR_STACK, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname),-1,E_OFT_STRUCT, sizeof(field_obj_type), \
        sizeof(st_obj_desc_##field_obj_type)/sizeof(st_obj_desc_t), \
        (void *)&st_obj_desc_##field_obj_type\
        , 0 /* parent_expand */\
    },
// 定义自定义结构体数组成员信息 堆内存
#define ST_OBJ_DESC_JSON_DEF_OBJS_HEAP(obj_type_def, fieldname, lenghtname, field_obj_type, jsonname) \
    { #jsonname, E_OFT_ARR_HEAP, offsetof(obj_type_def, fieldname), sizeof(((obj_type_def*)0)->fieldname),offsetof(obj_type_def, lenghtname),E_OFT_STRUCT, sizeof(field_obj_type), \
        sizeof(st_obj_desc_##field_obj_type)/sizeof(st_obj_desc_t), \
        (void *)&st_obj_desc_##field_obj_type\
        , 0 /* parent_expand */\
    },

#define ST_OBJ_DESC_BYTES_FUN(obj_type_def) \
    \
    static int o2b_##obj_type_def(obj_type_def *obj_ptr, uint8_t *bytes_buf, uint64_t buf_len) \
    { \
        return  object_co_bytes(#obj_type_def, obj_ptr, st_obj_desc_##obj_type_def, sizeof(st_obj_desc_##obj_type_def)/sizeof(st_obj_desc_t), bytes_buf, buf_len, 1); \
    } \
    \
    static int b2o_##obj_type_def(uint8_t *bytes_buf, uint64_t buf_len, obj_type_def *obj_ptr) \
    { \
        return bytes_co_object(#obj_type_def, bytes_buf, buf_len, obj_ptr, st_obj_desc_##obj_type_def, sizeof(st_obj_desc_##obj_type_def)/sizeof(st_obj_desc_t), 1); \
    } \
    \
    static int get_bytes_size_##obj_type_def(obj_type_def *obj_ptr) \
    { \
        return get_bytes_size(#obj_type_def, obj_ptr, st_obj_desc_##obj_type_def, sizeof(st_obj_desc_##obj_type_def)/sizeof(st_obj_desc_t));\
    }


#define ST_OBJ_DESC_JSON_FUN(obj_type_def) \
    \
    static int o2j_##obj_type_def(obj_type_def *obj_ptr, char *json_str, uint64_t buf_len) \
    { \
        return  object_co_json_str(#obj_type_def, obj_ptr, st_obj_desc_##obj_type_def, sizeof(st_obj_desc_##obj_type_def)/sizeof(st_obj_desc_t), json_str, buf_len, 1); \
    } \
    \
    static int j2o_##obj_type_def(char *json_str, uint64_t buf_len, obj_type_def *obj_ptr) \
    { \
        return json_str_co_object(#obj_type_def, json_str, buf_len, obj_ptr, st_obj_desc_##obj_type_def, sizeof(st_obj_desc_##obj_type_def)/sizeof(st_obj_desc_t), 1); \
    }\
    \
    static int get_json_size_##obj_type_def(obj_type_def *obj_ptr) \
    { \
        return get_json_str_size(#obj_type_def, obj_ptr, st_obj_desc_##obj_type_def, sizeof(st_obj_desc_##obj_type_def)/sizeof(st_obj_desc_t));\
    }

// 结束定义
#define ST_OBJ_DESC_END(obj_type_def) \
    }; \
    static int obj_free_##obj_type_def(obj_type_def *obj_ptr) \
    { \
        return object_free(#obj_type_def, obj_ptr, st_obj_desc_##obj_type_def, sizeof(st_obj_desc_##obj_type_def)/sizeof(st_obj_desc_t));\
    } 

#define ST_OBJ_DESC_BYTES_END(obj_type_def) \
    ST_OBJ_DESC_END(obj_type_def)\
    ST_OBJ_DESC_BYTES_FUN(obj_type_def)

#define ST_OBJ_DESC_JSON_END(obj_type_def) \
    ST_OBJ_DESC_END(obj_type_def)\
    ST_OBJ_DESC_JSON_FUN(obj_type_def)

// 对象结构释放
int object_free(const char *name, void *obj, void *obj_desc_ptr, int32_t obj_field_count);


#ifdef __cplusplus
}
#endif

#endif // __XJ_OBJECT_DESCRIPTOR_H__